function addEvent(o, e, f, s){
    var r = o[r = "_" + (e = "on" + e)] = o[r] || (o[e] ? [[o[e], o]] : []), a, c, d;
    r[r.length] = [f, s || o], o[e] = function(e){
        try{
            (e = e || event).preventDefault || (e.preventDefault = function(){e.returnValue = false;});
            e.stopPropagation || (e.stopPropagation = function(){e.cancelBubble = true;});
            e.target || (e.target = e.srcElement || null);
            e.key = (e.which + 1 || e.keyCode + 1) - 1 || 0;
        }catch(f){}
        for(d = 1, f = r.length; f; r[--f] && (a = r[f][0], o = r[f][1], a.call ? c = a.call(o, e) : (o._ = a, c = o._(e), o._ = null), d &= c !== false));
        return e = null, !!d;
    }
};

function removeEvent(o, e, f, s){
    for(var i = (e = o["_on" + e] || []).length; i;)
        if(e[--i] && e[i][0] == f && (s || o) == e[i][1])
            return delete e[i];
    return false;
};

function getTarget(event) {
  if (event && event.target) {
    return event.target;
  }
  if (window.event) {
    return window.event.srcElement;
  }
}

/**
 * Devolve um array com todos os elementos do documento de um determinado tipo
 * que sejam da classe css especificada.
 * @param tag tipo (ex: input, button)
 * @param className class
 * @return todos os elementos que se encaixarem nos criterios.
 */
function getElementsByTagAndClassName(tag, className) {
  var result = new Array();
  var elements = document.getElementsByTagName(tag);
  for (var i=0; i<elements.length; i++) {
    var element = elements.item(i);
    if (element.className == className) {
      result.push(element);
    }
  }
  return result;
}

function addEventByTagAndClassName(tag, className, eventName, listener) {
  var elements  = getElementsByTagAndClassName(tag, className);
  for (i=0; i<elements.length; i++) {
    addEvent(elements[i], eventName, listener);
  }
}
